package com.notes.businessScenario.expiredOrders.redisZet;

import com.notes.utils.JedisUtil;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import java.util.Calendar;
import java.util.Set;

/**
 * @author tiny
 * @date 2021/12/20 19:44
 * @Description:
 */
public class RedisDemo {

    private static Jedis jedis = JedisUtil.getJedis();

    public static void main(String[] args) {
        RedisDemo redisDemo = new RedisDemo();
        redisDemo.produceDelayMessage();

        redisDemo.consumerDelayMessage();
    }

    public void produceDelayMessage(){
        for(int i=1;i<=5;i++){
            //延迟3秒
            Calendar cal1 = Calendar.getInstance();
            cal1.add(Calendar.SECOND, 10 + i * 5);

            int secondslater = (int) (cal1.getTimeInMillis() / 1000 );
            jedis.zadd("OrderId",secondslater,"1000000"+i); //添加到期时间戳(score),与订单号(member)
            System.out.println(System.currentTimeMillis()+"ms:redis生成了一个订单任务：订单ID为"+"1000000"+i);

        }
    }

    //消费者，取订单
    public void consumerDelayMessage(){

        while(true){
            //zset是按score大小升序排序的
            Set<Tuple> items = jedis.zrangeWithScores("OrderId", 0, 1); //取排序的第一个元素
            boolean isTimeOut = isTimeOut(items);
            if( !isTimeOut ){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                continue;
            }

            String orderId = ((Tuple)items.toArray()[0]).getElement();
//                jedis.zrem("OrderId", orderId);
            Long zrem = jedis.zrem("OrderId", orderId); //同步删除
            //防止多线程时消费了同样的订单
            if(zrem!=null && zrem.compareTo(0L)>0 ){
                //处理订单的逻辑操作
                System.out.println(System.currentTimeMillis() +"ms:redis消费了一个任务：消费的订单OrderId为"+orderId);
            }
        }
    }

    /**
     * 是否有任务时间到了
     * @param items
     * @return
     */
    private boolean isTimeOut(Set<Tuple> items) {
        if( CollectionUtils.isEmpty(items) ) {
            System.out.println("当前没有等待的任务");
            return false;
        }
        int  score = (int) ((Tuple)items.toArray()[0]).getScore();
        Calendar cal = Calendar.getInstance();
        int nowSecond = (int) (cal.getTimeInMillis() / 1000);
        //当前时间大于过期时间
        if( nowSecond >= score ){
            return true;
        }
        System.out.println("当前还没有到执行时间的等待任务");
        return false;
    }

}
